package code

import (
	"bytes"
	"context"
	"encoding/base64"
	"github.com/golang/freetype"
	"image"
	"image/color"
	"image/jpeg"
	"math/rand"
	"net/http"
	"os"
	"strconv"
	"strings"
	"time"
	"ubt-aio-service/app/pkg/conf"
	"ubt-aio-service/app/pkg/db"
	"ubt-aio-service/app/pkg/logger"
	"ubt-aio-service/app/utils"
)

// NewImg 生成图片
func NewImg(r *http.Request, dx, dy int) *utils.ResJson {
	// 新建一个指定大小的RGBA位图
	img := image.NewNRGBA(image.Rect(0, 0, dx, dy))
	// 画白背景
	for y := 0; y < dy; y++ {
		for x := 0; x < dx; x++ {
			img.Set(x, y, color.White)
		}
	}
	// 读取字体文件
	fontBytes, err := os.ReadFile(conf.Cfg.AppConf.FontPath)
	if err == nil {
		font, _ := freetype.ParseFont(fontBytes)
		rand.New(rand.NewSource(time.Now().UnixNano()))
		num1 := rand.Intn(10)
		num2 := rand.Intn(10)
		sum := num1 + num2
		codeShow := strconv.Itoa(num1) + "+" + strconv.Itoa(num2)
		codeChk := strconv.Itoa(sum)
		charLen := len(codeShow)
		x := 5
		for i := 0; i < charLen; i++ {
			cont := freetype.NewContext()
			cont.SetDPI(72)
			cont.SetFont(font)
			cont.SetFontSize(25)
			cont.SetClip(img.Bounds())
			cont.SetDst(img)
			c := uint8(rand.Intn(255))
			m := uint8(rand.Intn(255))
			y := uint8(rand.Intn(255))
			k := uint8(128)
			curColor := color.RGBA{R: c, G: m, B: y, A: k}
			src := image.NewUniform(curColor)
			cont.SetSrc(src)
			pt := freetype.Pt(x, rand.Intn(10)+25) // 字出现的位置
			x += 20
			curChar := codeShow[i : i+1]
			_, _ = cont.DrawString(curChar, pt)
		}
		// 将验证码字符中存入缓冲数据库中
		curIp := utils.GetClientIP(r)
		if curIp != "" {
			curIp = strings.Replace(curIp, ".", "", -1)
			curIp = "code" + curIp
		} else {
			curIp = "code127001"
		}
		ctx := context.Background()
		if _, err = db.RdsCli.Get(ctx, curIp).Result(); err == nil {
			_ = db.RdsCli.Del(ctx, curIp)
		}
		// 设置失效时间（5分钟）
		if err = db.RdsCli.Set(ctx, curIp, codeChk, 300*time.Second).Err(); err != nil {
			return utils.RedisErr
		}
		newBuff := bytes.NewBuffer(nil)
		var data string
		_ = jpeg.Encode(newBuff, img, nil)
		dist := make([]byte, 2500)
		base64.StdEncoding.Encode(dist, newBuff.Bytes())
		idx := bytes.IndexByte(dist, 0)
		data = string(dist[0:idx])
		return &utils.ResJson{Code: utils.Succeed.Code, Msg: utils.Succeed.Msg, Data: data}
	}
	logger.Error("图片生成失败。" + err.Error())
	return utils.SysErr
}

// GetCodeImg 获取系统验证码图片
func GetCodeImg(r *http.Request) string {
	curIp := utils.GetClientIP(r)
	if curIp != "" {
		curIp = strings.Replace(curIp, ".", "", -1)
		curIp = "code" + curIp
	} else {
		curIp = "code127001"
	}
	ctx := context.Background()
	sysCode, _ := db.RdsCli.Get(ctx, curIp).Result()
	return sysCode
}
